﻿/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../data_struct/head.h"
#include "../callback/head.h"
#include "../property/head.h"
#include "../threads/head.h"
#include "../variant/head.h"
#include "../big_buf/head.h"
#include "../serial/head.h"
#include "../heart/head.h"
#include "../list/head.h"
#include "../lock/head.h"
#include "../buf/head.h"
#include "../msg/head.h"
#include "../macro/head.h"
#include "hook.h"
#include "mgr.h"

namespace xos_box
{

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    static xos_common::i_common * common_ptr = 0;
    static xos::i_misc * misc_ptr = 0;
    static xos::i_crt * crt_ptr = 0;

    static xos_log::i_log * log_ptr = 0;
    static xos::i_xos * xos_ptr = 0;

    static mgr * package_mgr_ptr = 0;

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    mgr::mgr()
    {
        init_data();
    }

    mgr::~mgr()
    {}

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int mgr::static_init( xos::i_xos * pXosImpl, xos_common::i_common * pCommon, xos_log::i_log * pLog, i_box_mgr ** ppv )
    {
        int ret = 0;

        mgr::T * pObj = 0;

        if( ( 0 == ret ) && package_mgr_ptr )
        {
            ret = 1;
        }

        if( 0 == ret )
        {
            ret = pCommon->create( xos_common::enumObjType::OBJ_MISC, ( void ** )&misc_ptr );
        }

        if( 0 == ret )
        {
            ret = pXosImpl->create( xos::i_xos::XOS_OBJ_CRT, ( void ** )&crt_ptr );
        }

        if( 0 == ret )
        {
            common_ptr = pCommon;
            xos_ptr = pXosImpl;
            log_ptr = pLog;
        }

        if( 0 == ret )
        {
            pObj = new mgr::T;
            if( !pObj )
            {
                ret = 1;
            }
        }

        if( 0 == ret )
        {
            ret = pObj->init();
            if( 0 != ret )
            {
                ret = 1;
            }
        }

        if( 0 == ret )
        {
            package_mgr_ptr = pObj;
            *ppv = pObj;
            pObj = 0;
        }

        xos_stl::release_interface( pObj );

        return ret;
    }

    xos_common::i_common * mgr::common()
    {
        return common_ptr;
    }

    xos_log::i_log * mgr::log()
    {
        return log_ptr;
    }

    xos::i_misc * mgr::misc()
    {
        return misc_ptr;
    }

    xos::i_crt * mgr::crt()
    {
        return crt_ptr;
    }

    xos_box::i_big_buf * mgr::big_buf()
    {
        xos_box::i_big_buf * pRet = 0;
        get()->create( enumObj::BOX_OBJ_BIG_BUF, ( void ** )&pRet );
        return pRet;
    }

    xos_box::i_buf * mgr::buf()
    {
        xos_box::i_buf * pRet = 0;
        get()->create( enumObj::BOX_OBJ_BUF, ( void ** )&pRet );
        return pRet;
    }

    xos::i_xos * mgr::xos()
    {
        return xos_ptr;
    }

    mgr * mgr::get()
    {
        return package_mgr_ptr;
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int mgr::create( enumObj eType, void ** ppv )
    {
        int ret = 0;

        xos::i_release * pRet = 0;

        switch( eType )
        {
        case enumObj::BOX_OBJ_LIST:
            {
                list_impl * p = 0;
                ret = xos_stl::init_pool_item( p, true );
                pRet = p;
            }
            break;

        case enumObj::BOX_OBJ_ACCEPTOR:
            {
                heart_acceptor * p = 0;
                ret = xos_stl::init_pool_item( p, true );
                pRet = p;
            }
            break;
        case enumObj::BOX_OBJ_HEART:
            {
                heart_impl * p = 0;
                ret = xos_stl::init_pool_item( p, true );
                pRet = p;
            }
            break;

        case enumObj::BOX_OBJ_CALLBACK:
            {
                callback_impl * p = 0;
                ret = xos_stl::init_pool_item( p, true );
                pRet = p;
            }
            break;

        case enumObj::BOX_OBJ_LOCK_NUM:
            {
                lock_num * p = 0;
                ret = xos_stl::init_pool_item( p, true );
                pRet = p;
            }
            break;

        case enumObj::BOX_OBJ_LOCK_OBJ:
            {
                lock_obj * p = 0;
                ret = xos_stl::init_pool_item( p, true );
                pRet = p;
            }
            break;

        case enumObj::BOX_OBJ_BIG_BUF:
            {
                big_buf_impl * p = 0;
                ret = xos_stl::init_pool_item( p, true );
                pRet = p;
            }
            break;
        case enumObj::BOX_OBJ_BUF:
            {
                buf_impl * p = 0;
                ret = xos_stl::init_pool_item( p, true );
                pRet = p;
            }
            break;
        case enumObj::BOX_OBJ_MSG:
            {
                msg_impl * p = 0;
                ret = xos_stl::init_pool_item( p, true );
                pRet = p;
            }
            break;

        case enumObj::BOX_OBJ_PROPERTY:
            {
                property_impl * p = 0;
                ret = xos_stl::init_pool_item( p, true );
                pRet = p;
            }
            break;
        case enumObj::BOX_OBJ_VARIANT:
            {
                variant_impl * p = 0;
                ret = xos_stl::init_pool_item( p, true );
                pRet = p;
            }
            break;
        case enumObj::BOX_OBJ_SERIAL:
            {
                serial_impl * p = 0;
                ret = xos_stl::init_pool_item( p, true );
                pRet = p;
            }
            break;
        default:
            break;
            {
                ret = 1;
            }
        }

        if( 0 != ret )
        {
            xos_stl::release_interface( pRet );
        }
        else
        {
            *ppv = pRet;
        }

        return ret;
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int mgr::put_back_to_pool( T * pT, bool bLock )
    {
        int ret = 0;
        delete this;
        return ret;
    }

    int mgr::init_data()
    {
        int ret = 0;
        return ret;
    }

    int mgr::init()
    {
        int ret = 0;

        if( 0 == ret )
        {
            log()->add_log_module( LOG_NAME, 1 );
            log()->add_log_module( LOG_NAME, 2 );
            log()->add_log_module( LOG_NAME, 3 );
            log()->add_log_module( LOG_NAME, 4 );
        }

        if( 0 == ret )
        {
            ret = hook::init();
        }

        return ret;
    }

    int mgr::term()
    {
        int ret = 0;

        {
            hook::term();
            xos_stl::release_interface( misc_ptr );
            xos_stl::release_interface( crt_ptr );
        }
        {
            package_mgr_ptr = 0;
            common_ptr = 0;
            log_ptr = 0;
            xos_ptr = 0;
        }

        return ret;
    }

} // xos_box
